using System.Text;

namespace array_demo.Model
{

    /// <summary>
    /// 创建自定义数组
    /// </summary>
    public class Array1<E>
    {
        private E[] data;
        private int N;

        public Array1(int capacity)
        {
            data = new E[capacity];
            N = 0;
        }

        public Array1() : this(10)
        {

        }

        /// <summary>
        /// 获取容量
        /// </summary>
        public int Capacity
        {
            get
            {
                return data.Length;
            }
        }

        /// <summary>
        /// 获取数组的个数
        /// </summary>
        public int Count
        {
            get
            {
                return N;
            }
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="index"></param>
        /// <param name="e"></param>
        public void Add(int index, E e)
        {
            if (index < 0 || index > N)
            {
                throw new AggregateException("数组索引越界");
            }

            if (N == data.Length)
            {
                ResetCapacity(2 * data.Length);
            }

            for (int i = N - 1; i >= index; i--)
            {
                data[i + 1] = data[i];
            }
            data[index] = e;
            N++;
        }

        /// <summary>
        /// 添加到数组最后
        /// </summary>
        /// <param name="e"></param>
        public void AddLast(E e)
        {
            Add(N, e);
        }

        /// <summary>
        /// 添加数据到数组最前面
        /// </summary>
        /// <param name="e"></param>
        public void AddFirst(E e)
        {
            Add(0, e);
        }


        public bool IsEmpty()
        {
            if (N == 0)
                return true;
            return false;
        }


        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public E GetByIndex(int index)
        {
            if (index < 0 || index > N)
            {
                throw new AggregateException("数组索引越界");
            }
            return data[index];
        }

        public E GetLast()
        {
            return GetByIndex(N - 1);
        }


        public E GetFirst()
        {
            return GetByIndex(0);
        }


        public bool Exist(E e)
        {
            bool flag = false;
            for (int i = 0; i < N; i++)
            {
                if (data[i].ToString() == e.ToString())
                {
                    flag = true;
                }
            }
            return flag;
        }


        /// <summary>
        /// 获取索引
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public int IndexOf(E e)
        {
            for (int i = 0; i < N; i++)
            {
                if (data[i].ToString() == e.ToString())
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// 修改元素
        /// </summary>
        /// <param name="index"></param>
        /// <param name="e"></param>
        /// <exception cref="AggregateException"></exception>
        public void Update(int index, E e)
        {
            if (index < 0 || index > N)
            {
                throw new AggregateException("数组索引越界");
            }
            data[index] = e;
        }

        /// <summary>
        /// 删除元素
        /// </summary>
        /// <param name="index"></param>
        /// <param name="e"></param>
        public E DeleteAt(int index)
        {
            if (index < 0 || index > N)
            {
                throw new AggregateException("数组索引越界");
            }

            if (N == 0)
            {
                throw new AggregateException("数组为空");
            }

            E del = data[index];

            for (int i = index + 1; i <= N - 1; i++)
            {
                data[i - 1] = data[i];
            }

            N--;

            data[N] = default(E);

            if (N == data.Length / 4)
            {
                ResetCapacity(data.Length / 2);
            }

            return del;
        }


        public E DeleteLast()
        {
            return DeleteAt(N - 1);
        }

        public E DeleteFirst()
        {
            return DeleteAt(0);
        }


        /// <summary>
        /// 容量扩充
        /// </summary>
        /// <param name="newCapacity"></param>
        private void ResetCapacity(int newCapacity)
        {
            E[] newData = new E[newCapacity];
            for (int i = 0; i < N; i++)
            {
                newData[i] = data[i];
            }
            data = newData;
        }




        /// <summary>
        /// 重写转字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            // stringBuilder.Append(string.Format("Array1: count:{0} capacity ={1}\n", N, data.Length));
            stringBuilder.Append("[");
            for (int i = 0; i < N; i++)
            {
                stringBuilder.Append(data[i]);
                if (i != N - 1)
                {
                    stringBuilder.Append(",");
                }
            }
            stringBuilder.Append("]");
            return stringBuilder.ToString();
        }
    }

}